import cn from 'classnames';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import fetch from 'API/fetch';
import { datetime } from '../../../../common/formatter';
import resultNumbers from '../resultNumbers';
import Label from '../../../components/Label';
import RaskSelect from '../../../components/RaskSelect';
import { Spin } from 'antd';

import VulTrend from './VulTrend';
import VulCategory from './VulCategory';
import SslDetail from './SslDetail';
import VulDetails from './VulDetails';
import s from './style.module.css';
import { WARN_LEVEL_MAP } from '../../../../common/constants';
class Weakness extends Component {
	static propTypes = {
		className: PropTypes.string,
		jobId: PropTypes.string,
		ignoredWarnIdMap: PropTypes.object,
		client: PropTypes.shape({
			query: PropTypes.func,
		}),
		getDropdownRef: PropTypes.func,
		result: PropTypes.shape({
			startTime: PropTypes.date,
			endTime: PropTypes.date,
			warnings: PropTypes.arrayOf(
				PropTypes.shape({
					id: PropTypes.string,
					title: PropTypes.string,
					category: PropTypes.string,
					affects: PropTypes.string,
				})
			),
		}),
		prevResult: PropTypes.shape({
			startTime: PropTypes.date,
			endTime: PropTypes.date,
			warnings: PropTypes.arrayOf(
				PropTypes.shape({
					id: PropTypes.string,
					title: PropTypes.string,
					level: PropTypes.number,
					category: PropTypes.string,
					affects: PropTypes.string,
				})
			),
		}),
		sslResult: PropTypes.object,
		sslPrevResult: PropTypes.object,
		vulResults: PropTypes.array,
		httpResults: PropTypes.array,
		protocol: PropTypes.string,
		resultNumbers: PropTypes.arrayOf(
			PropTypes.shape({
				warnCount: PropTypes.number,
				highWarnCount: PropTypes.number,
				mediumWarnCount: PropTypes.number,
				lowWarnCount: PropTypes.number,
				datetime: PropTypes.date,
			})
		),
		cydResultNumbers: PropTypes.arrayOf(
			PropTypes.shape({
				datetime: PropTypes.string,
				taskId: PropTypes.string,
			})
		),
		sslResultNumbers: PropTypes.arrayOf(
			PropTypes.shape({
				datetime: PropTypes.string,
				taskId: PropTypes.string,
			})
		),
		data: PropTypes.shape({
			vulResults: PropTypes.array,
			sslResults: PropTypes.array,
		}),
	};

	static defaultProps = {
		className: '',
	};

	constructor(props) {
		super(props);
		this.state = {
			loading: false,
			allData: [],
			dateRask: { detectTime: 'last', detectType: 'last' },
			detectTime: 'last',
			date: [],
			cydFilter: {},
			vulRes: [],
			taskCategory: {},
			tableData: [],
			resultNumbers: [],
		};
	}

	getResultData = (range = 'last', startTime, endTime) => {
		if (!this.props.jobId) {
			return false;
		}
		this.setState({ loading: true });
		let url = `/api/v2/repodatas/report-task?jobId=${this.props.jobId}&taskType=vul&range=${range}`;
		if (range === 'range') {
			url += `&startTime=${new Date(startTime).toISOString()}
			&endTime=${new Date(endTime).toISOString()}`;
		} else {
			url += `&limit=10`;
		}
		fetch(url, {
			method: 'GET',
		})
			.then(res => {
				if (range === 'range') {
					this.init(res.TaskData);
				} else {
					this.init(res.TaskData[0] ? [res.TaskData[0]] : []);
				}
				const restt = resultNumbers(res.TaskData);
				const resultNumbers_ = restt || [];
				this.setState({
					allData: res.TaskData,
					resultNumbers: resultNumbers_,
					vulRes: restt,
				});
			})
			.finally(() => {
				this.setState({
					loading: false,
				});
			});
	};

	handleDateRask = val => {
		this.setState({ dateRask: val });
		// if (val.detectTime === 'prev') {
		// 	this.init([this.state.allData[1]]);
		// 	return false;
		// }
		const obj = { range: val.detectTime };
		if (obj.range === 'range') {
			obj.startTime = val.dateRange[0];
			obj.endTime = val.dateRange[1];
		}
		this.getResultData(obj.range, obj.startTime, obj.endTime);
	};

	warningStatsBuilder = (warning = {}) => {
		let text;
		if (warning.ignoredTime) {
			text = '已忽略';
		} else if (warning.isResolved) {
			text = '已修复';
		} else {
			text = '待修复';
		}
		return text;
	};

	init = d => {
		const tasks = d;
		let tableData = [];
		const t = {};
		if (!tasks.length) {
			this.setState({ tableData: [] });
			return false;
		}
		for (let i = 0; i < tasks.length; i++) {
			const resWarnings = tasks[i].result.warnings.reduce((res, item, idx) => {
				const row = {
					...item,
					date: datetime(tasks[i].endTime),
					affects: item.affects || '',
					description: item?.description || '',
					category: item?.category || '',
					level: WARN_LEVEL_MAP[item.level],
					levelNum: item.level,
					status: this.warningStatsBuilder(item),
					_id: `${i}-${idx}`,
				};
				res.push(row);
				t[row?.category || ''] = true;
				return res;
			}, []);
			tableData = tableData.concat(resWarnings);
			tableData = tableData.sort((a, b) => {
				return a.levelNum > b.levelNum ? -1 : 1;
			});
			this.setState({ tableData: tableData });
		}
		this.setState({ taskCategory: t });
	};

	componentDidMount() {
		this.getResultData('last');
	}

	render() {
		const {
			className,
			jobId,
			ignoredWarnIdMap,
			getDropdownRef,
			sslResult,
			sslPrevResult,
			protocol,
			type,
		} = this.props;
		const { date, dateRask, vulRes, loading } = this.state;
		const detectTime = dateRask.detectTime;
		const lastDate =
			detectTime === 'last'
				? this?.props?.result?.endTime
				: this?.props?.prevResult?.endTime;
		console.log(type);
		return (
			<div className={cn(className, s.weakness)}>
				{type === 'weakness' && (
					<div className={s.head}>
						<div className={s.left}>
							<Label className={s.label}>Web漏洞</Label>
							{detectTime && (
								<div className={s.date}>
									<span className={s.time}>{datetime(lastDate)}</span>
								</div>
							)}
						</div>
						<RaskSelect
							value={dateRask}
							onChange={this.handleDateRask}
							resultLength={vulRes.length || 0}
						/>
					</div>
				)}
				{type === 'host' && (
					<div className={s.head}>
						<div className={s.left}>
							<Label className={s.label}>主机漏洞</Label>
							{detectTime && (
								<div className={s.date}>
									<span className={s.time}>{datetime(lastDate)}</span>
								</div>
							)}
						</div>
						<RaskSelect
							value={dateRask}
							onChange={this.handleDateRask}
							resultLength={vulRes.length || 0}
						/>
					</div>
				)}
				<div className={s.content}>
					{type === 'weakness' && (
						<div className={s.main}>
							<Spin spinning={loading}>
								<VulTrend
									key={`${jobId}-${detectTime}-${JSON.stringify(date)}`}
									className={cn(s.tend, s.row)}
									jobId={jobId}
									resultNumbers={vulRes}
									detectTime={detectTime}
									dateRask={dateRask}
								/>
								<VulCategory
									key={detectTime}
									jobId={jobId}
									className={s.row}
									resultNumbers={this.state.tableData}
									detectTime={detectTime}
									dateRange={date}
									type={type}
								/>
								<VulDetails
									className={s.row}
									key={JSON.stringify(date)}
									jobId={jobId}
									resultNumbers={vulRes}
									detectTime={detectTime}
									dateRange={date}
									getDropdownRef={getDropdownRef}
									tableData={this.state.tableData}
									taskCategory={this.state.taskCategory}
									ignoredWarnIdMap={ignoredWarnIdMap}
									type={type}
								/>
							</Spin>
						</div>
					)}
					{type === 'host' && (
						<div className={s.main}>
							<Spin spinning={loading}>
								<VulTrend
									key={`${jobId}-${detectTime}-${JSON.stringify(date)}`}
									className={cn(s.tend, s.row)}
									jobId={jobId}
									resultNumbers={vulRes}
									detectTime={detectTime}
									dateRask={dateRask}
								/>
								<VulCategory
									key={detectTime}
									jobId={jobId}
									className={s.row}
									resultNumbers={this.state.tableData}
									detectTime={detectTime}
									dateRange={date}
									type={type}
								/>
								<VulDetails
									className={s.row}
									key={JSON.stringify(date)}
									jobId={jobId}
									resultNumbers={vulRes}
									detectTime={detectTime}
									dateRange={date}
									getDropdownRef={getDropdownRef}
									tableData={this.state.tableData}
									taskCategory={this.state.taskCategory}
									ignoredWarnIdMap={ignoredWarnIdMap}
									type={type}
								/>
							</Spin>
						</div>
					)}
					{type === 'ssl' && (
						<SslDetail
							protocol={protocol}
							className={s.configDetail}
							jobId={jobId}
							result={sslResult}
							prevResult={sslPrevResult}
							getDropdownRef={getDropdownRef}
							taskType="ssl"
						/>
					)}
				</div>
			</div>
		);
	}
}

export default Weakness;
